﻿using System;
using System.Collections;
using System.Globalization;

namespace CyberConnect.Insteon.Messaging
{
    [System.ComponentModel.ImmutableObject(true)]
    public class DeviceIdentification : DeviceMessageDecorator
    {
        private readonly DeviceAddress _DeviceInfo;

        public DeviceIdentification(DeviceMessage message, DeviceAddress deviceInfo)
            : base(message)
        {
            this._DeviceInfo = deviceInfo;
        }

        protected DeviceAddress DeviceInfo { get { return this._DeviceInfo; } }

        #region Category Definitions

        private static Hashtable Categories = new Hashtable()
            {
                {"0x00", new Hashtable() //Connectivity
                    {
                        {"0x00", "InsteonDevice"},
                        {"0x04", "ControlLinc [2430]"},
                        {"0x05", "RemoteLinc [2440]"},
                        {"0x06", "Icon Tabletop Controller [2830]"},
                        {"0x08", "EZBridge/EZServer"},
                        {"0x09", "SignalLinc RF Signal Enhancer [2442]"},
                        {"0x0A", "Balboa Instrument's Poolux LCD Controller"},
                        {"0x0B", "Access Point [2443]"},
                        {"0x0C", "IES Color Touchscreen"},
                    }
                },
                {"0x01", new Hashtable() //Lighting
                    {
                        {"0x00", "LampLinc V2 [2456D3]"},
                        {"0x01", "SwitchLinc V2 Dimmer 600W [2476D]"},
                        {"0x02", "In-LineLinc Dimmer [2475D]"},
                        {"0x03", "Icon Switch Dimmer [2876D]"},
                        {"0x04", "SwitchLinc V2 Dimmer 1000W [2476DH]"},
                        {"0x05", "KeypadLinc Dimmer Countdown Timer [2484DWH8]"},
                        {"0x06", "LampLinc 2-Pin [2456D2]"},
                        {"0x07", "Icon LampLinc V2 2-Pin [2856D2]"},
                        {"0x08", "SwitchLinc Dimmer Count-down Timer [2484DWH8]"},
                        {"0x09", "KeypadLinc Dimmer [2486D]"},
                        {"0x0A", "Icon In-Wall Controller [2886D]"},
                        {"0x0B", "Access Point LampLinc [2458D3]"},
                        {"0x0C", "KeypadLinc Dimmer - 8-Button defaulted mode [2486DWH8]"},
                        {"0x0D", "SocketLinc [2454D]"},
                        {"0x0E", "LampLinc Dimmer, Dual-Band [2457D3]"},
                        {"0x13", "ICON SwitchLinc Dimmer for Lixar/Bell Canada [2676D-B]"},
                        {"0x17", "ToggleLinc Dimmer [2466D]"},
                        {"0x18", "Icon SL Dimmer Inline Companion [2474D]"},
                        {"0x19", "SwitchLinc 800W"},
                        {"0x1A", "In-LineLinc Dimmer with Sense [2475D2]"},
                        {"0x1B", "KeypadLinc 6-button Dimmer [2486DWH6]"},
                        {"0x1C", "KeypadLinc 8-button Dimmer [2486DWH8]"},
                        {"0x1D", "SwitchLinc Dimmer 1200W [2476D]"}
                    }
                },
                {"0x02", new Hashtable() //Relays
                    {
                        {"0x05", "KeypadLinc Relay - 8-Button defaulted mode [2486SWH8]"},
                        {"0x06", "Outdoor ApplianceLinc [2456S3E]"},
                        {"0x07", "TimerLinc [2456ST3]"},
                        {"0x08", "OutletLinc [2473S]"},
                        {"0x09", "ApplianceLinc [2456S3]"},
                        {"0x0A", "SwitchLinc Relay [2476S]"},
                        {"0x0B", "Icon On Off Switch [2876S]"},
                        {"0x0C", "Icon Appliance Adapter [2856S3]"},
                        {"0x0D", "ToggleLinc Relay [2466S]"},
                        {"0x0E", "SwitchLinc Relay Countdown Timer [2476ST]"},
                        {"0x0F", "KeypadLinc On/Off Switch [2486SWH6]"},
                        {"0x10", "In-LineLinc Relay [2475D]"},
                        {"0x11", "EZSwitch30 (240V, 30A load controller)"},
                        {"0x12", "Icon SL Relay Inline Companion"},
                        {"0x13", "ICON SwitchLinc Relay for Lixar/Bell Canada [2676R-B]"},
                        {"0x14", "In-LineLinc Relay with Sense [2475S2]"},
                        {"0x16", "SwitchLinc Relay with Sense [2476S2]"}
                    }
                }
            };

        #endregion Category Definitions

        public static string GetDeviceName(byte category, byte subcategory)
        {
            return (string)(((Hashtable)Categories[string.Format(CultureInfo.InvariantCulture, "0x{0}", category.ToString("X2", CultureInfo.InvariantCulture))])[string.Format(CultureInfo.InvariantCulture, "0x{0}", subcategory.ToString("X2", CultureInfo.InvariantCulture))]);
        }

        public string DeviceName
        {
            get
            {
                return DeviceIdentification.GetDeviceName(this.DeviceInfo.High, this.DeviceInfo.Middle);
            }
        }

        public byte Category { get { return this.DeviceInfo.High; } }

        public byte Subcategory { get { return this.DeviceInfo.Middle; } }

        public static bool IsIdentification(DeviceMessage message)
        {
            return message == null ? false : (message.Configuration.MessageType == MessageType.Broadcast && message.Command.Command1 == 0x01);
        }

        public static explicit operator DeviceIdentification(DeviceMessageIncoming incoming)
        {
            return FromDeviceMessageIncoming(incoming);
        }

        public static DeviceIdentification FromDeviceMessageIncoming(DeviceMessageIncoming incoming)
        {
            if (incoming == null) { throw new ArgumentNullException("incoming"); }

            return new DeviceIdentification(incoming.Message, incoming.DirectToAddress);
        }
    }
}